﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace AAA.Base.Image
{
    public class ImageHelper
    {
        public static double GetBestPercent(int rWidth, int rHeight, int mWidth, int mHeight)
        {

            double p = 1, d = 0.01;

            int w = rWidth, h = rHeight;

            if (w > mWidth * 2 || h > mHeight * 2)
            {

                p = 0.5;

                if (w > mWidth * 3 || h > mHeight * 3)
                {

                    p = 0.35;

                    d = 0.002;

                }

                else

                    d = 0.005;

            }




            while (w > mWidth || h > mHeight)
            {

                p = p - d;

                w = (int)(rWidth * p);

                h = (int)(rHeight * p);

            }

            return p;

        }




        public static System.Drawing.Image MakeSmallImg(System.Drawing.Image imgSource, System.Double templateWidth, System.Double templateHeight)
        {



            System.Drawing.Image myImage = imgSource;

            System.Double newWidth = myImage.Width, newHeight = myImage.Height;

            if (myImage.Width > myImage.Height || myImage.Width == myImage.Height)
            {

                if (myImage.Width > templateWidth)
                {

                    newWidth = templateWidth;

                    newHeight = myImage.Height * (newWidth / myImage.Width);

                }

            }

            else
            {

                if (myImage.Height > templateHeight)
                {

                    newHeight = templateHeight;

                    newWidth = myImage.Width * (newHeight / myImage.Height);

                }

            }

            System.Drawing.Size mySize = new Size((int)newWidth, (int)newHeight);

            System.Drawing.Image bitmap = new System.Drawing.Bitmap(mySize.Width, mySize.Height);

            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);

            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            g.Clear(System.Drawing.Color.Transparent);

            g.DrawImage(myImage, new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
                        new System.Drawing.Rectangle(0, 0, myImage.Width, myImage.Height),
                                        System.Drawing.GraphicsUnit.Pixel);

            myImage.Dispose();

            g.Dispose();
            return bitmap;            

        }

        //將RGB轉換為YCbCr
        public static YCbCr RGB2YCbCr(Color cSource)
        {
            YCbCr yCbCr = new YCbCr();

            yCbCr.Y = 0.2989 * (double)cSource.R + 0.5866 * (double)cSource.G + 0.1145 * (double)cSource.B;
            yCbCr.Cb = -0.1687 * (double)cSource.R - 0.3313 * (double)cSource.G + 0.5000 * (double)cSource.B + 128.0;
            yCbCr.Cr = 0.5000 * (double)cSource.R - 0.4184 * (double)cSource.G - 0.0816 * (double)cSource.B + 128.0;

            return yCbCr;
        }

        //以RGB值去除背景
        public static Bitmap CutBackground(Bitmap backgroundImage, Bitmap sourceImage, int iThreshold)
        {
            return CutBackground(backgroundImage, sourceImage, iThreshold, iThreshold, iThreshold);
        }

        //以RGB值去除背景
        public static Bitmap CutBackground(Bitmap backgroundImage, Bitmap sourceImage, int iThresholdR, int iThresholdG, int iThresholdB)
        {
            return CutBackground(backgroundImage, sourceImage, iThresholdR, iThresholdG, iThresholdB, Color.Black);
        }

        //以RGB值去除背景
        public static Bitmap CutBackground(Bitmap backgroundImage, Bitmap sourceImage, int iThresholdR, int iThresholdG, int iThresholdB, Color cMaskColor)
        {
            return CutBackground(backgroundImage, sourceImage, iThresholdR, iThresholdG, iThresholdB, cMaskColor, cMaskColor);
        }

        //以RGB值去除背景
        public static Bitmap CutBackground(Bitmap backgroundImage, Bitmap sourceImage, int iThresholdR, int iThresholdG, int iThresholdB, Color cMaskColor, Color cFillColor)
        {            
            Bitmap resultImage = null;

            /*
            if ((backgroundImage.Width != sourceImage.Width) ||
                (backgroundImage.Height != sourceImage.Height))
                return resultImage;
            */

            if (Math.Abs(backgroundImage.Width - sourceImage.Width) > 10 ||
                Math.Abs(backgroundImage.Height - sourceImage.Height) > 10)
                return resultImage;

            try
            {
                resultImage = new Bitmap(Math.Min(backgroundImage.Width, sourceImage.Width), Math.Min(backgroundImage.Height, sourceImage.Height));

                for (int i = 0; i < resultImage.Width; i++)
                    for (int j = 0; j < resultImage.Height; j++)
                    {
                        if ((Math.Abs(sourceImage.GetPixel(i, j).R - backgroundImage.GetPixel(i, j).R) < iThresholdR) &&
                            (Math.Abs(sourceImage.GetPixel(i, j).G - backgroundImage.GetPixel(i, j).G) < iThresholdG) &&
                            (Math.Abs(sourceImage.GetPixel(i, j).B - backgroundImage.GetPixel(i, j).B) < iThresholdB))
                        {
                            resultImage.SetPixel(i, j, cMaskColor);
                        }
                        else
                        {
                            if (cMaskColor == cFillColor)
                                resultImage.SetPixel(i, j, sourceImage.GetPixel(i, j));
                            else
                                resultImage.SetPixel(i, j, cFillColor);
                        }
                    }
            }
            catch (Exception e)
            {
            }
            return resultImage;
        }

        //以YCbCr值去除背景
        public static Bitmap CutBackgroundYCbCr(Bitmap backgroundImage, Bitmap sourceImage, int iThreshold)
        {
            return CutBackgroundYCbCr(backgroundImage, sourceImage, iThreshold, iThreshold, iThreshold);
        }

        //以YCbCr值去除背景
        public static Bitmap CutBackgroundYCbCr(Bitmap backgroundImage, Bitmap sourceImage, int iThresholdY, int iThresholdCb, int iThresholdCr)
        {
            return CutBackgroundYCbCr(backgroundImage, sourceImage, iThresholdY, iThresholdCb, iThresholdCr, Color.Black);
        }

        //以YCbCr值去除背景
        public static Bitmap CutBackgroundYCbCr(Bitmap backgroundImage, Bitmap sourceImage, int iThresholdY, int iThresholdCb, int iThresholdCr, Color cMaskColor)
        {
            return CutBackgroundYCbCr(backgroundImage, sourceImage, iThresholdY, iThresholdCb, iThresholdCr, cMaskColor, cMaskColor);
        }

        //以YCbCr值去除背景
        public static Bitmap CutBackgroundYCbCr(Bitmap backgroundImage, Bitmap sourceImage, int iThresholdY, int iThresholdCb, int iThresholdCr, Color cMaskColor, Color cFillColor)
        {
            Bitmap resultImage = null;
            YCbCr backgroundYCbCr;
            YCbCr sourceYCbCr;
            if ((backgroundImage.Width != sourceImage.Width) ||
                (backgroundImage.Height != sourceImage.Height))
                return resultImage;

            try
            {
                resultImage = new Bitmap(backgroundImage.Width, backgroundImage.Height);

                for (int i = 0; i < backgroundImage.Width; i++)
                    for (int j = 0; j < backgroundImage.Height; j++)
                    {
                        backgroundYCbCr = ImageHelper.RGB2YCbCr(backgroundImage.GetPixel(i, j));
                        sourceYCbCr = ImageHelper.RGB2YCbCr(sourceImage.GetPixel(i, j));

                        if((Math.Abs(backgroundYCbCr.Y - sourceYCbCr.Y) < iThresholdY) &&
                           (Math.Abs(backgroundYCbCr.Cb - sourceYCbCr.Cb) < iThresholdCb) &&
                           (Math.Abs(backgroundYCbCr.Cr - sourceYCbCr.Cr) < iThresholdCr))
                        {
                            resultImage.SetPixel(i, j, cMaskColor);
                        }
                        else
                        {
                            if (cMaskColor == cFillColor)
                                resultImage.SetPixel(i, j, sourceImage.GetPixel(i, j));
                            else
                                resultImage.SetPixel(i, j, cFillColor);
                        }
                    }
            }
            catch (Exception e)
            {
            }
            return resultImage;
        }

        //依YCbCr值做圖形遮罩, 用於取得皮膚區塊
        public static Bitmap MaskByYCbCr(Bitmap sourceImage, int iCbMin, int iCbMax, int iCrMin, int iCrMax, Color cMaskColor, Color cFillColor)
        {
            Bitmap resultImage = new Bitmap(sourceImage.Width, sourceImage.Height);
            YCbCr yCbCr;

            for(int i = 0; i < sourceImage.Width; i++)
                for(int j = 0; j < sourceImage.Height; j++)
                {
                    yCbCr = RGB2YCbCr(sourceImage.GetPixel(i, j));

                    if((yCbCr.Cb >= iCbMin) && (yCbCr.Cb <= iCbMax) &&
                       (yCbCr.Cr >= iCrMin) && (yCbCr.Cr <= iCrMax))
                        resultImage.SetPixel(i, j, cFillColor);
                    else
                        resultImage.SetPixel(i, j, cMaskColor);
                }

            return resultImage;
        }

        //圖形處理:侵蝕
        public static Bitmap Erosion(Bitmap sourceImage, Color cMaskColor, Color cFillColor)
        {
            Bitmap resultImage = new Bitmap(sourceImage.Width, sourceImage.Height);
            int iFillRGB = cFillColor.ToArgb();

            //為減少if在for loop中的判斷次數, 區分為四個角, 四個邊線及中間區塊處理, 以增快處理速度

            //Left-Upper Pixel
            resultImage.SetPixel(0, 0, cMaskColor);

            //Right-Upper Pixel
            resultImage.SetPixel(sourceImage.Width - 1, 0, cMaskColor);

            //Left-Bottom Pixel
            resultImage.SetPixel(0, sourceImage.Height - 1, cMaskColor);

            //Right-Bottom Pixel
            resultImage.SetPixel(sourceImage.Width - 1, sourceImage.Height - 1, cMaskColor);

            // Horizontal Pixel
            for (int i = 1; i < sourceImage.Width - 1; i++)
            {
                // Top
                resultImage.SetPixel(i, 0, cMaskColor);

                // Bottom
                resultImage.SetPixel(i, sourceImage.Height - 1, cMaskColor);
            }

            // Vertical Pixel
            for (int i = 1; i < sourceImage.Height - 1; i++)
            {
                // Left
                resultImage.SetPixel(0, i, cMaskColor);

                // Right
                resultImage.SetPixel(sourceImage.Width - 1, i, cMaskColor);
            }

            // Center Pixel
            for (int i = 1; i < sourceImage.Width - 1; i++)
                for (int j = 1; j < sourceImage.Height - 1; j++)
                {
                    if (sourceImage.GetPixel(i, j).ToArgb() != iFillRGB)
                    {
                        resultImage.SetPixel(i, j, cMaskColor);
                        continue;
                    }

                    if ((sourceImage.GetPixel(i, j - 1).ToArgb() == iFillRGB) &&
                        (sourceImage.GetPixel(i, j + 1).ToArgb() == iFillRGB) &&
                        (sourceImage.GetPixel(i - 1, j).ToArgb() == iFillRGB) &&
                        (sourceImage.GetPixel(i + 1, j).ToArgb() == iFillRGB))
                        resultImage.SetPixel(i, j, cFillColor);
                    else
                        resultImage.SetPixel(i, j, cMaskColor);
                }

            return resultImage;
        }

        //圖形處理:膨漲
        public static Bitmap Dilation(Bitmap sourceImage, Color cMaskColor, Color cFillColor)
        {
            Bitmap resultImage = new Bitmap(sourceImage.Width, sourceImage.Height);
            int iFillRGB = cFillColor.ToArgb();

            //為減少if在for loop中的判斷次數, 區分為四個角, 四個邊線及中間區塊處理, 以增快處理速度

            //Left-Upper Pixel
            if ((sourceImage.GetPixel(1, 0).ToArgb() == iFillRGB) ||
                (sourceImage.GetPixel(0, 1).ToArgb() == iFillRGB) ||
                (sourceImage.GetPixel(0, 0).ToArgb() == iFillRGB))
                resultImage.SetPixel(0, 0, cFillColor);
            else
                resultImage.SetPixel(0, 0, cMaskColor);

            //Right-Upper Pixel            
            if ((sourceImage.GetPixel(sourceImage.Width - 2, 0).ToArgb() == iFillRGB) ||
                (sourceImage.GetPixel(sourceImage.Width - 1, 1).ToArgb() == iFillRGB) ||
                (sourceImage.GetPixel(sourceImage.Width - 1, 0).ToArgb() == iFillRGB))
                resultImage.SetPixel(sourceImage.Width - 1, 0, cFillColor);
            else
                resultImage.SetPixel(sourceImage.Width - 1, 0, cMaskColor);

            //Left-Bottom Pixel
            if ((sourceImage.GetPixel(0, sourceImage.Height - 2).ToArgb() == iFillRGB) ||
                (sourceImage.GetPixel(1, sourceImage.Height - 1).ToArgb() == iFillRGB) ||
                (sourceImage.GetPixel(0, sourceImage.Height - 1).ToArgb() == iFillRGB))
                resultImage.SetPixel(0, sourceImage.Height - 1, cFillColor);
            else
                resultImage.SetPixel(0, sourceImage.Height - 1, cMaskColor);

            //Right-Bottom Pixel
            if ((sourceImage.GetPixel(sourceImage.Width - 2, sourceImage.Height - 1).ToArgb() == iFillRGB) ||
                (sourceImage.GetPixel(sourceImage.Width - 1, sourceImage.Height - 2).ToArgb() == iFillRGB) ||
                (sourceImage.GetPixel(sourceImage.Width - 1, sourceImage.Height - 1).ToArgb() == iFillRGB))
                resultImage.SetPixel(sourceImage.Width - 1, sourceImage.Height - 1, cFillColor);
            else
                resultImage.SetPixel(sourceImage.Width - 1, sourceImage.Height - 1, cMaskColor);

            // Horizontal Pixel
            for (int i = 1; i < sourceImage.Width - 1; i++)
            {
                // Top
                if (sourceImage.GetPixel(i, 0).ToArgb() == cFillColor.ToArgb())
                {
                    resultImage.SetPixel(i, 0, cFillColor);
                    continue;
                }

                if ((sourceImage.GetPixel(i - 1, 0).ToArgb() == iFillRGB) ||
                    (sourceImage.GetPixel(i + 1, 0).ToArgb() == iFillRGB) ||
                    (sourceImage.GetPixel(i, 1).ToArgb() == iFillRGB))
                    resultImage.SetPixel(i, 0, cFillColor);
                else
                    resultImage.SetPixel(i, 0, cMaskColor);

                // Bottom
                if (sourceImage.GetPixel(i, sourceImage.Height - 1).ToArgb() == iFillRGB)
                {
                    resultImage.SetPixel(i, sourceImage.Height - 1, cFillColor);
                    continue;
                }

                if ((sourceImage.GetPixel(i - 1, sourceImage.Height - 1).ToArgb() == iFillRGB) ||
                    (sourceImage.GetPixel(i + 1, sourceImage.Height - 1).ToArgb() == iFillRGB) ||
                    (sourceImage.GetPixel(i, sourceImage.Height - 2) == cFillColor))
                    resultImage.SetPixel(i, sourceImage.Height - 1, cFillColor);
                else
                    resultImage.SetPixel(i, sourceImage.Height - 1, cMaskColor);                
            }

            // Vertical Pixel
            for (int i = 1; i < sourceImage.Height - 1; i++)
            {
                // Left
                if (sourceImage.GetPixel(0, i).ToArgb() == iFillRGB)
                {
                    resultImage.SetPixel(0, i, cFillColor);
                    continue;
                }

                if ((sourceImage.GetPixel(0, i - 1).ToArgb() == iFillRGB) ||
                    (sourceImage.GetPixel(0, i + 1).ToArgb() == iFillRGB) ||
                    (sourceImage.GetPixel(1, i).ToArgb() == iFillRGB))
                    resultImage.SetPixel(0, i, cFillColor);
                else
                    resultImage.SetPixel(0, i, cMaskColor);

                // Right
                if (sourceImage.GetPixel(sourceImage.Width - 1, i).ToArgb() == iFillRGB)
                {
                    resultImage.SetPixel(sourceImage.Width - 1, i, cFillColor);
                    continue;
                }

                if ((sourceImage.GetPixel(sourceImage.Width - 1, i - 1).ToArgb() == iFillRGB) ||
                    (sourceImage.GetPixel(sourceImage.Width - 1, i + 1).ToArgb() == iFillRGB) ||
                    (sourceImage.GetPixel(sourceImage.Width - 2, i).ToArgb() == iFillRGB))
                    resultImage.SetPixel(sourceImage.Width - 1, i, cFillColor);
                else
                    resultImage.SetPixel(sourceImage.Width - 1, i, cMaskColor);
            }

            // Center Pixel
            for(int i = 1; i < sourceImage.Width - 1; i++)
                for (int j = 1; j < sourceImage.Height - 1; j++)
                {
                    if (sourceImage.GetPixel(i, j).ToArgb() == iFillRGB)
                    {
                        resultImage.SetPixel(i, j, cFillColor);
                        continue;
                    }

                    if ((sourceImage.GetPixel(i, j - 1).ToArgb() == iFillRGB) ||
                        (sourceImage.GetPixel(i, j + 1).ToArgb() == iFillRGB) ||
                        (sourceImage.GetPixel(i - 1, j).ToArgb() == iFillRGB) ||
                        (sourceImage.GetPixel(i + 1, j).ToArgb() == iFillRGB))
                        resultImage.SetPixel(i, j, cFillColor);
                    else
                        resultImage.SetPixel(i, j, cMaskColor);
                }

            return resultImage;
        }

        //圖形處理:將圖案由RGB空間轉換為YCbCr空間
        public static Bitmap ConvertRGB2YCbCr(Bitmap sourceImage)
        {
            Bitmap resultImage = new Bitmap(sourceImage.Width, sourceImage.Height);
            YCbCr yCbCr;

            for (int i = 0; i < sourceImage.Width; i++)
                for (int j = 0; j < sourceImage.Height; j++)
                {
                    yCbCr = RGB2YCbCr(sourceImage.GetPixel(i, j));
                    resultImage.SetPixel(i, j, Color.FromArgb((int)yCbCr.Y, (int)yCbCr.Cb, (int)yCbCr.Cr));
                }
            return resultImage;
        }

        //以4-Connected Component演算法區分區塊
        public static Bitmap ConnectedComponent(Bitmap sourceImage, Color cMaskColor, BlockLabel blockLabel, int iEdge)
        {
            Bitmap resultImage = null;
            int iMaskRGB = cMaskColor.ToArgb();
            int iUpRGB;
            int iLeftRGB;
            int iUpLabel;
            int iLeftLabel;            
            int iLabelCount = 0;
            Point pointCurrent;
            Point pLeftTop;
            Point pRightBottom;

            List<Point> lstMaxBlock;

            for(int i = 1; i < sourceImage.Width - 1; i++)
                for (int j = 1; j < sourceImage.Height - 1; j++)
                {
                    if (sourceImage.GetPixel(i, j).ToArgb() == iMaskRGB)
                        continue;

                    pointCurrent = new Point(i, j);
                    iUpRGB = sourceImage.GetPixel(i, j - 1).ToArgb();
                    iLeftRGB = sourceImage.GetPixel(i - 1, j).ToArgb();

                    iUpLabel = blockLabel.GetPointLabel(new Point(i, j - 1));
                    iLeftLabel = blockLabel.GetPointLabel(new Point(i - 1, j));

                    if((iUpRGB == iMaskRGB) && (iLeftRGB == iMaskRGB))
                    {
                        blockLabel.AddPoint(iLabelCount, pointCurrent);
                        iLabelCount++;
                    }
                    else if((iUpRGB != iMaskRGB) && (iLeftRGB != iMaskRGB))
                    {
                        if (iLeftLabel == iUpLabel)
                        {
                            blockLabel.AddPoint(iLeftLabel, pointCurrent);
                        }
                        else
                        {
                            blockLabel.AddPoint(Math.Min(iLeftLabel, iUpLabel), pointCurrent);
                            blockLabel.MergeLabel(Math.Max(iLeftLabel, iUpLabel), Math.Min(iLeftLabel, iUpLabel));
                        }
                    }
                    else if (iUpRGB != iMaskRGB)
                    {
                        blockLabel.AddPoint(iUpLabel, pointCurrent);
                    }
                    else
                    {
                        blockLabel.AddPoint(iLeftLabel, pointCurrent);
                    }
                }

            lstMaxBlock = blockLabel.GetMaxBlock();
            pLeftTop = blockLabel.GetLeftTop(blockLabel.MaxLabel);
            pRightBottom = blockLabel.GetRightBottom(blockLabel.MaxLabel);

            int iWidth = pRightBottom.X - pLeftTop.X + 1;
            int iHeight = pRightBottom.Y - pLeftTop.Y + 1;

            int iXOffset = (iWidth < iHeight) ? (int)((iHeight - iWidth) / 2.0) : 0;
            int iYOffset = (iWidth > iHeight) ? (int)((iWidth - iHeight) / 2.0) : 0;

            iXOffset += iEdge;
            iYOffset += iEdge;

            resultImage = new Bitmap(Math.Max(iWidth, iHeight) + 2 * iEdge, Math.Max(iWidth, iHeight) + 2 * iEdge);

            int iX = 0;
            int iY = 0;
            foreach (Point point in lstMaxBlock)
            {
                resultImage.SetPixel(point.X - pLeftTop.X + iXOffset, point.Y - pLeftTop.Y + iYOffset, sourceImage.GetPixel(point.X, point.Y));
                iX += point.X;
                iY += point.Y;
            }

            resultImage.SetPixel(iX / lstMaxBlock.Count - pLeftTop.X + iXOffset, iY / lstMaxBlock.Count - pLeftTop.Y + iYOffset, Color.Red);

            //計算區塊的質心, 並標上紅色十字
            blockLabel.MaxCenter = new Point(iX / lstMaxBlock.Count - pLeftTop.X + iXOffset, iY / lstMaxBlock.Count - pLeftTop.Y + iYOffset);

            resultImage.SetPixel(blockLabel.MaxCenter.X - 1, blockLabel.MaxCenter.Y, Color.Red);
            resultImage.SetPixel(blockLabel.MaxCenter.X + 1, blockLabel.MaxCenter.Y, Color.Red);
            resultImage.SetPixel(blockLabel.MaxCenter.X, blockLabel.MaxCenter.Y - 1, Color.Red);
            resultImage.SetPixel(blockLabel.MaxCenter.X, blockLabel.MaxCenter.Y + 1, Color.Red);
            resultImage.SetPixel(blockLabel.MaxCenter.X, blockLabel.MaxCenter.Y, Color.Red);

            return resultImage;
        }

        //圖形處理:邊緣偵測
        public static Bitmap EdgeDetect(Bitmap sourceImage, Color cMaskColor)
        {
            Bitmap resultImage = new Bitmap(sourceImage.Width, sourceImage.Height);
            int iMaskRGB = cMaskColor.ToArgb();

            for (int i = 1; i < sourceImage.Width - 1; i++)
                for (int j = 1; j < sourceImage.Height - 1; j++)
                {
                    if (sourceImage.GetPixel(i, j).ToArgb() == iMaskRGB)
                        continue;

                    if ((sourceImage.GetPixel(i - 1, j - 1).ToArgb() != iMaskRGB) &&
                        (sourceImage.GetPixel(i, j - 1).ToArgb() != iMaskRGB) &&
                        (sourceImage.GetPixel(i + 1, j - 1).ToArgb() != iMaskRGB) &&
                        (sourceImage.GetPixel(i - 1, j).ToArgb() != iMaskRGB) &&
                        (sourceImage.GetPixel(i, j).ToArgb() != iMaskRGB) &&
                        (sourceImage.GetPixel(i + 1, j).ToArgb() != iMaskRGB) &&
                        (sourceImage.GetPixel(i - 1, j + 1).ToArgb() != iMaskRGB) &&
                        (sourceImage.GetPixel(i, j + 1).ToArgb() != iMaskRGB) &&
                        (sourceImage.GetPixel(i + 1, j + 1).ToArgb() != iMaskRGB))
                        resultImage.SetPixel(i, j, cMaskColor);
                    else
                        resultImage.SetPixel(i, j, sourceImage.GetPixel(i, j));
                }
            return resultImage;
        }

        //計算垂直投影的距離
        public static int[] CalculateVerticalDistance(Bitmap sourceImage, Color cBackground)
        {
            int[] iReturns = new int[sourceImage.Width];
            int iBackgroundRGB = cBackground.ToArgb();

            for (int i = 0; i < sourceImage.Width; i++)
            {
                 for (int j = 0; j < sourceImage.Height; j++)
                {
                    if (sourceImage.GetPixel(i, j).ToArgb() != iBackgroundRGB)
                    {
                        iReturns[i] = sourceImage.Height - j;
                        sourceImage.SetPixel(i, j, Color.Red);
                        break;
                    }
                }
 
            }
            return iReturns;
        }

        //計算中心點至區塊的距離
        public static int[] CalculateDistance(Bitmap sourceImage, Color cBackground)
        {
            int iBackgroundRGB = cBackground.ToArgb();
            int[] iReturns = new int[4];
            int iXOrigin = sourceImage.Width / 2;
            int iYOrigin = sourceImage.Height / 2;

            for (int i = 0; i <= iYOrigin; i++)
            {
                if (sourceImage.GetPixel(iXOrigin, i).ToArgb() != iBackgroundRGB)
                {
                    iReturns[0] = iYOrigin - i;
                    break;
                }
            }

            for (int i = sourceImage.Width - 1; i >= iXOrigin; i--)
            {
                if (sourceImage.GetPixel(i, iYOrigin).ToArgb() != iBackgroundRGB)
                {
                    iReturns[1] = i - iXOrigin;
                    break;
                }
            }

            for (int i = sourceImage.Height - 1; i >= iYOrigin; i--)
            {
                if (sourceImage.GetPixel(iXOrigin, i).ToArgb() != iBackgroundRGB)
                {
                    iReturns[2] = i - iYOrigin;
                    break;
                }
            }

            for (int i = 0; i < iXOrigin; i++)
            {
                if (sourceImage.GetPixel(i, iYOrigin).ToArgb() != iBackgroundRGB)
                {
                    iReturns[3] = iXOrigin - i;
                    break;
                }
            }

            return iReturns;
        }

        //圖形平移
        public static Bitmap MoveImage(Bitmap sourceImage, int iX, int iY)
        {
            //create a new empty bitmap to hold rotated image
            Bitmap returnBitmap = new Bitmap(sourceImage.Width, sourceImage.Height);
            //make a graphics object from the empty bitmap
            Graphics g = Graphics.FromImage(returnBitmap);
            //move rotation point to center of image
            g.TranslateTransform(iX, iY);
            //draw passed in image onto graphics object
            g.DrawImage(sourceImage, new Point(0, 0));
            return returnBitmap;
        }

        //圖形旋轉
        public static Bitmap RotateImage(Bitmap sourceImage, float fAngle)
        {
            return RotateImage(sourceImage, fAngle, new Point(sourceImage.Width / 2, sourceImage.Height / 2));
        }

        public static Bitmap RotateImage(Bitmap sourceImage, float fAngle, Point pOrigin)
        {
            if (fAngle == 0)
                return sourceImage;
            //create a new empty bitmap to hold rotated image
            Bitmap returnBitmap = new Bitmap(sourceImage.Width, sourceImage.Height);
            //make a graphics object from the empty bitmap
            Graphics g = Graphics.FromImage(returnBitmap);
            //move rotation point to center of image
            g.TranslateTransform((float)pOrigin.X, (float)pOrigin.Y);
            //rotate
            g.RotateTransform(fAngle);
            //move image back
            g.TranslateTransform(-(float)pOrigin.X, -(float)pOrigin.Y);
            //draw passed in image onto graphics object
            g.DrawImage(sourceImage, new Point(0, 0));
            return returnBitmap;
        }

        //由圖形左上角開始, 擷取指定的長寬
        public static Bitmap CutImage(Bitmap sourceImage, int iWidth, int iHeight)
        {
            Bitmap returnImage = new Bitmap(iWidth, iHeight);

            for (int i = 0; i < iWidth; i++)
                for (int j = 0; j < iHeight; j++)
                    returnImage.SetPixel(i, j, sourceImage.GetPixel(i, j));

            return returnImage;
        }

        //統計圖形RGB數量
        public static Dictionary<string, int> CalulateRGB(Bitmap sourceImage, int RGBInterval)
        {
            Dictionary<string, int> resultCount = new Dictionary<string,int>();
            try
            {
                for (int i = 0; i < sourceImage.Width; i++)
                {
                    for (int j = 0; j < sourceImage.Height; j++)
                    {
                        string ColorKey = (sourceImage.GetPixel(i, j).R / RGBInterval) + "-" + (sourceImage.GetPixel(i, j).G / RGBInterval) + "-" + (sourceImage.GetPixel(i, j).B / RGBInterval);
                        if (!resultCount.ContainsKey(ColorKey))
                        {
                            resultCount.Add(ColorKey, 1);
                        }
                        else
                        {
                            resultCount[ColorKey] = resultCount[ColorKey] + 1;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message.ToString());
            }
            return resultCount;
        }
    }
}
